/*!
 * \file TraderCTP.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief CTP交易接口实现头文件
 * 
 * \details 该文件定义了TraderCTP类，实现了完整的CTP期货交易功能：
 *          - 基于上期技术CTP API 6.3.15版本的交易接口封装
 *          - 实现ITraderApi标准交易接口，提供统一的交易API
 *          - 继承CThostFtdcTraderSpi，处理CTP交易回调事件
 *          - 支持期货、期权等多种金融产品的交易
 *          - 提供完整的交易生命周期管理（连接、认证、登录、交易、查询）
 *          - 实现订单管理、持仓查询、资金查询、成交查询等核心功能
 *          - 支持多种订单类型和交易指令
 *          - 提供错误处理和状态管理机制
 *          - 集成WonderTrader数据结构转换和缓存机制
 *          - 支持异步查询队列和线程安全操作
 * 
 * \note CTP是中国期货市场主流的交易系统，该实现提供了完整的期货交易功能
 * \warning 使用前需要正确配置CTP交易前置地址、经纪商代码、用户认证信息等参数
 */
#pragma once

#include <string>
#include <queue>
#include <stdint.h>

#include "../Includes/WTSTypes.h"
#include "../Includes/ITraderApi.h"
#include "../Includes/WTSCollection.hpp"

#include "../API/CTP6.3.15/ThostFtdcTraderApi.h"

#include "../Share/StdUtils.hpp"
#include "../Share/DLLHelper.hpp"
#include "../Share/WtKVCache.hpp"

USING_NS_WTP;

/*!
 * \class TraderCTP
 * \brief CTP交易接口实现类
 * 
 * \details 该类实现了完整的CTP期货交易功能，主要特性包括：
 *          
 *          核心功能：
 *          - 实现ITraderApi标准接口，提供统一的交易API
 *          - 继承CThostFtdcTraderSpi，处理CTP原生回调事件
 *          - 支持期货、期权等多种金融产品交易
 *          
 *          连接管理：
 *          - 自动连接CTP交易前置服务器
 *          - 支持用户认证和登录验证
 *          - 实现连接状态监控和自动重连
 *          - 处理心跳检测和网络异常
 *          
 *          交易功能：
 *          - 支持限价单、市价单等多种订单类型
 *          - 实现开仓、平仓、平今、平昨等交易指令
 *          - 提供订单撤销和修改功能
 *          - 支持批量订单操作
 *          
 *          查询功能：
 *          - 资金账户查询和实时更新
 *          - 持仓信息查询和持仓明细
 *          - 订单状态查询和历史订单
 *          - 成交记录查询和成交明细
 *          - 结算单查询和确认
 *          
 *          数据转换：
 *          - CTP原生数据结构与WonderTrader数据结构互转
 *          - 价格类型、方向类型、时间条件等枚举转换
 *          - 订单状态和错误信息标准化处理
 *          
 *          缓存机制：
 *          - 委托单号和订单号的双向映射缓存
 *          - 持仓数据缓存和增量更新
 *          - 成交数据缓存和历史记录
 *          
 *          线程安全：
 *          - 异步查询队列管理
 *          - 线程安全的数据访问
 *          - 原子操作保证数据一致性
 * 
 * \note 该实现基于CTP API 6.3.15版本，兼容主流期货公司的CTP系统
 * \warning 交易操作涉及资金安全，使用时需要充分测试和风险控制
 */
class TraderCTP : public ITraderApi, public CThostFtdcTraderSpi
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * 初始化TraderCTP实例，设置默认参数和状态
	 */
	TraderCTP();
	
	/*!
	 * \brief 析构函数
	 * 
	 * 清理资源，断开连接，释放内存
	 */
	virtual ~TraderCTP();

public:
	/*!
	 * \enum WrapperState
	 * \brief 交易接口状态枚举
	 * 
	 * 定义CTP交易接口的各种连接和登录状态
	 */
	typedef enum
	{
		WS_NOTLOGIN,		///< 未登录状态
		WS_LOGINING,		///< 正在登录状态
		WS_LOGINED,			///< 已登录状态
		WS_LOGINFAILED,		///< 登录失败状态
		WS_CONFIRM_QRYED,	///< 结算单查询完成状态
		WS_CONFIRMED,		///< 结算单已确认状态
		WS_ALLREADY			///< 全部就绪状态（可以进行交易）
	} WrapperState;

private:
	/*!
	 * \brief 确认结算单
	 * \return 操作结果代码
	 * 
	 * 向CTP服务器发送结算单确认请求
	 */
	int confirm();

	/*!
	 * \brief 查询结算单确认状态
	 * \return 操作结果代码
	 * 
	 * 查询当前结算单是否已确认
	 */
	int queryConfirm();

	/*!
	 * \brief 用户认证
	 * \return 操作结果代码
	 * 
	 * 向CTP服务器发送用户认证请求
	 */
	int authenticate();

	/*!
	 * \brief 执行登录操作
	 * \return 操作结果代码
	 * 
	 * 向CTP服务器发送用户登录请求
	 */
	int doLogin();

	//////////////////////////////////////////////////////////////////////////
	// ITraderApi接口实现
public:
	/*!
	 * \brief 初始化交易接口
	 * \param params 配置参数
	 * \return 是否初始化成功
	 * 
	 * \details 从配置参数中读取CTP连接信息：
	 *          - broker: 经纪商代码
	 *          - front: 交易前置地址
	 *          - user: 用户名
	 *          - pass: 密码
	 *          - appid: 应用程序标识
	 *          - authcode: 认证码
	 *          - quick: 是否快速启动
	 *          - flowdir: 流文件目录
	 */
	virtual bool init(WTSVariant* params) override;

	/*!
	 * \brief 释放交易接口资源
	 * 
	 * 清理所有资源，断开连接，停止工作线程
	 */
	virtual void release() override;

	/*!
	 * \brief 注册交易回调接口
	 * \param listener 交易事件回调接口
	 * 
	 * 注册用于接收交易事件通知的回调接口
	 */
	virtual void registerSpi(ITraderSpi *listener) override;

	/*!
	 * \brief 生成委托单号
	 * \param buffer 输出缓冲区
	 * \param length 缓冲区长度
	 * \return 是否生成成功
	 * 
	 * 生成唯一的委托单号，用于标识订单
	 */
	virtual bool makeEntrustID(char* buffer, int length) override;

	/*!
	 * \brief 连接CTP服务器
	 * 
	 * 建立与CTP交易前置服务器的连接
	 */
	virtual void connect() override;

	/*!
	 * \brief 断开CTP服务器连接
	 * 
	 * 断开与CTP交易前置服务器的连接
	 */
	virtual void disconnect() override;

	/*!
	 * \brief 检查连接状态
	 * \return 是否已连接
	 * 
	 * 检查与CTP服务器的连接状态
	 */
	virtual bool isConnected() override;

	/*!
	 * \brief 用户登录
	 * \param user 用户名
	 * \param pass 密码
	 * \param productInfo 产品信息
	 * \return 登录结果代码
	 * 
	 * 向CTP服务器发送用户登录请求
	 */
	virtual int login(const char* user, const char* pass, const char* productInfo) override;

	/*!
	 * \brief 用户登出
	 * \return 登出结果代码
	 * 
	 * 向CTP服务器发送用户登出请求
	 */
	virtual int logout() override;

	/*!
	 * \brief 报单录入
	 * \param eutrust 委托单信息
	 * \return 操作结果代码
	 * 
	 * 向CTP服务器发送报单录入请求
	 */
	virtual int orderInsert(WTSEntrust* eutrust) override;

	/*!
	 * \brief 报单操作（撤单）
	 * \param action 报单操作信息
	 * \return 操作结果代码
	 * 
	 * 向CTP服务器发送报单撤销请求
	 */
	virtual int orderAction(WTSEntrustAction* action) override;

	/*!
	 * \brief 查询资金账户
	 * \return 操作结果代码
	 * 
	 * 查询当前资金账户信息
	 */
	virtual int queryAccount() override;

	/*!
	 * \brief 查询投资者持仓
	 * \return 操作结果代码
	 * 
	 * 查询当前持仓信息
	 */
	virtual int queryPositions() override;

	/*!
	 * \brief 查询报单
	 * \return 操作结果代码
	 * 
	 * 查询当前报单信息
	 */
	virtual int queryOrders() override;

	/*!
	 * \brief 查询成交
	 * \return 操作结果代码
	 * 
	 * 查询当前成交信息
	 */
	virtual int queryTrades() override;

	/*!
	 * \brief 查询结算单
	 * \param uDate 查询日期
	 * \return 操作结果代码
	 * 
	 * 查询指定日期的结算单信息
	 */
	virtual int querySettlement(uint32_t uDate) override;

	//////////////////////////////////////////////////////////////////////////
	// CTP交易接口实现
public:
	/*!
	 * \brief 前置连接成功回调
	 * 
	 * 当与CTP交易前置建立连接时触发
	 */
	virtual void OnFrontConnected() override;

	/*!
	 * \brief 前置连接断开回调
	 * \param nReason 断开原因
	 * 
	 * 当与CTP交易前置断开连接时触发
	 */
	virtual void OnFrontDisconnected(int nReason) override;

	/*!
	 * \brief 心跳超时警告回调
	 * \param nTimeLapse 超时时间
	 * 
	 * 当心跳检测超时时触发警告
	 */
	virtual void OnHeartBeatWarning(int nTimeLapse) override;

	/*!
	 * \brief 用户认证响应回调
	 * \param pRspAuthenticateField 认证响应信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理用户认证的响应结果
	 */
	virtual void OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 用户登录响应回调
	 * \param pRspUserLogin 登录响应信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理用户登录的响应结果
	 */
	virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 用户登出响应回调
	 * \param pUserLogout 登出信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理用户登出的响应结果
	 */
	virtual void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 结算单确认响应回调
	 * \param pSettlementInfoConfirm 结算单确认信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理结算单确认的响应结果
	 */
	virtual void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询结算单确认响应回调
	 * \param pSettlementInfoConfirm 结算单确认信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询结算单确认的响应结果
	 */
	virtual void OnRspQrySettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询资金账户响应回调
	 * \param pTradingAccount 资金账户信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询资金账户的响应结果
	 */
	virtual void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 报单录入响应回调
	 * \param pInputOrder 输入报单信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理报单录入的响应结果（通常是错误响应）
	 */
	virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 报单操作响应回调
	 * \param pInputOrderAction 报单操作信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理报单操作（撤单）的响应结果
	 */
	virtual void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询投资者持仓响应回调
	 * \param pInvestorPosition 投资者持仓信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询投资者持仓的响应结果
	 */
	virtual void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询结算单响应回调
	 * \param pSettlementInfo 结算单信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询结算单的响应结果
	 */
	virtual void OnRspQrySettlementInfo(CThostFtdcSettlementInfoField *pSettlementInfo, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询成交响应回调
	 * \param pTrade 成交信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询成交的响应结果
	 */
	virtual void OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 查询报单响应回调
	 * \param pOrder 报单信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理查询报单的响应结果
	 */
	virtual void OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 错误响应回调
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * 处理各种错误响应
	 */
	virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 报单回报回调
	 * \param pOrder 报单信息
	 * 
	 * 处理报单状态变化的主动推送
	 */
	virtual void OnRtnOrder(CThostFtdcOrderField *pOrder) override;

	/*!
	 * \brief 成交回报回调
	 * \param pTrade 成交信息
	 * 
	 * 处理成交信息的主动推送
	 */
	virtual void OnRtnTrade(CThostFtdcTradeField *pTrade) override;

	/*!
	 * \brief 报单录入错误回报回调
	 * \param pInputOrder 输入报单信息
	 * \param pRspInfo 响应信息
	 * 
	 * 处理报单录入失败的错误回报
	 */
	virtual void OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo) override;

private:
	/*!
	 * \brief 检查响应信息是否包含错误
	 * \param pRspInfo CTP响应信息
	 * \return 是否包含错误
	 * 
	 * 检查CTP响应信息中是否包含错误代码
	 */
	bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);

	// 数据类型转换函数（WonderTrader -> CTP）
	/*!
	 * \brief 转换价格类型
	 * \param priceType WonderTrader价格类型
	 * \param isCFFEX 是否为中金所合约
	 * \return CTP价格类型
	 */
	int wrapPriceType(WTSPriceType priceType, bool isCFFEX = false);
	
	/*!
	 * \brief 转换方向类型
	 * \param dirType WonderTrader方向类型
	 * \param offType WonderTrader开平类型
	 * \return CTP方向类型
	 */
	int wrapDirectionType(WTSDirectionType dirType, WTSOffsetType offType);
	
	/*!
	 * \brief 转换开平类型
	 * \param offType WonderTrader开平类型
	 * \return CTP开平类型
	 */
	int wrapOffsetType(WTSOffsetType offType);
	
	/*!
	 * \brief 转换时间条件
	 * \param timeCond WonderTrader时间条件
	 * \return CTP时间条件
	 */
	int	wrapTimeCondition(WTSTimeCondition timeCond);
	
	/*!
	 * \brief 转换操作标志
	 * \param actionFlag WonderTrader操作标志
	 * \return CTP操作标志
	 */
	int wrapActionFlag(WTSActionFlag actionFlag);

	// 数据类型转换函数（CTP -> WonderTrader）
	/*!
	 * \brief 转换价格类型
	 * \param priceType CTP价格类型
	 * \return WonderTrader价格类型
	 */
	WTSPriceType		wrapPriceType(TThostFtdcOrderPriceTypeType priceType);
	
	/*!
	 * \brief 转换方向类型
	 * \param dirType CTP方向类型
	 * \param offType CTP开平类型
	 * \return WonderTrader方向类型
	 */
	WTSDirectionType	wrapDirectionType(TThostFtdcDirectionType dirType, TThostFtdcOffsetFlagType offType);
	
	/*!
	 * \brief 转换持仓方向
	 * \param dirType CTP持仓方向
	 * \return WonderTrader方向类型
	 */
	WTSDirectionType	wrapPosDirection(TThostFtdcPosiDirectionType dirType);
	
	/*!
	 * \brief 转换开平类型
	 * \param offType CTP开平类型
	 * \return WonderTrader开平类型
	 */
	WTSOffsetType		wrapOffsetType(TThostFtdcOffsetFlagType offType);
	
	/*!
	 * \brief 转换时间条件
	 * \param timeCond CTP时间条件
	 * \return WonderTrader时间条件
	 */
	WTSTimeCondition	wrapTimeCondition(TThostFtdcTimeConditionType timeCond);
	
	/*!
	 * \brief 转换订单状态
	 * \param orderState CTP订单状态
	 * \return WonderTrader订单状态
	 */
	WTSOrderState		wrapOrderState(TThostFtdcOrderStatusType orderState);

	// 数据结构创建函数
	/*!
	 * \brief 创建订单信息对象
	 * \param orderField CTP订单字段
	 * \return WonderTrader订单信息对象
	 */
	WTSOrderInfo*	makeOrderInfo(CThostFtdcOrderField* orderField);
	
	/*!
	 * \brief 创建委托对象
	 * \param entrustField CTP输入订单字段
	 * \return WonderTrader委托对象
	 */
	WTSEntrust*		makeEntrust(CThostFtdcInputOrderField *entrustField);
	
	/*!
	 * \brief 创建错误对象
	 * \param rspInfo CTP响应信息
	 * \param ec WonderTrader错误代码
	 * \return WonderTrader错误对象
	 */
	WTSError*		makeError(CThostFtdcRspInfoField* rspInfo, WTSErroCode ec = WEC_NONE);
	
	/*!
	 * \brief 创建成交记录对象
	 * \param tradeField CTP成交字段
	 * \return WonderTrader成交信息对象
	 */
	WTSTradeInfo*	makeTradeRecord(CThostFtdcTradeField *tradeField);

	// 委托单号管理函数
	/*!
	 * \brief 生成委托单号
	 * \param buffer 输出缓冲区
	 * \param frontid 前置编号
	 * \param sessionid 会话编号
	 * \param orderRef 报单引用
	 */
	void			generateEntrustID(char* buffer, uint32_t frontid, uint32_t sessionid, uint32_t orderRef);
	
	/*!
	 * \brief 解析委托单号
	 * \param entrustid 委托单号
	 * \param frontid 前置编号（输出）
	 * \param sessionid 会话编号（输出）
	 * \param orderRef 报单引用（输出）
	 * \return 是否解析成功
	 */
	bool			extractEntrustID(const char* entrustid, uint32_t &frontid, uint32_t &sessionid, uint32_t &orderRef);

	/*!
	 * \brief 生成请求ID
	 * \return 新的请求ID
	 * 
	 * 生成唯一的请求ID，用于标识CTP请求
	 */
	uint32_t		genRequestID();

protected:
	// 连接配置参数
	std::string		m_strBroker;		///< 经纪商代码
	std::string		m_strFront;			///< 交易前置地址

	// 用户认证信息
	std::string		m_strUser;			///< 用户名
	std::string		m_strPass;			///< 密码
	std::string		m_strAppID;			///< 应用程序标识
	std::string		m_strAuthCode;		///< 认证码
	std::string		m_strProdInfo;		///< 产品信息

	bool			m_bQuickStart;		///< 是否快速启动

	std::string		m_strTag;			///< 标签
	std::string		m_strSettleInfo;	///< 结算单信息
	std::string		m_strUserName;		///< 用户名称
	std::string		m_strFlowDir;		///< 流文件目录

	// 回调接口和查询控制
	ITraderSpi*		m_sink;				///< 交易事件回调接口
	uint64_t		m_uLastQryTime;		///< 上次查询时间

	// CTP会话信息
	uint32_t					m_lDate;		///< 交易日期
	TThostFtdcFrontIDType		m_frontID;		///< 前置编号
	TThostFtdcSessionIDType		m_sessionID;	///< 会话编号
	std::atomic<uint32_t>		m_orderRef;		///< 报单引用（原子操作）

	WrapperState				m_wrapperState;	///< 接口状态

	// CTP API对象
	CThostFtdcTraderApi*		m_pUserAPI;		///< CTP交易API对象
	std::atomic<uint32_t>		m_iRequestID;	///< 请求ID计数器（原子操作）

	// 数据缓存
	typedef WTSHashMap<std::string> PositionMap;
	PositionMap*				m_mapPosition;	///< 持仓数据映射
	WTSArray*					m_ayTrades;		///< 成交数据数组
	WTSArray*					m_ayOrders;		///< 订单数据数组
	WTSArray*					m_ayPosDetail;	///< 持仓明细数组

	IBaseDataMgr*				m_bdMgr;		///< 基础数据管理器

	// 查询队列管理
	typedef std::queue<CommonExecuter>	QueryQue;
	QueryQue				m_queQuery;		///< 查询队列
	bool					m_bInQuery;		///< 是否正在查询
	StdUniqueMutex			m_mtxQuery;		///< 查询互斥锁
	uint64_t				m_lastQryTime;	///< 最后查询时间

	// 线程管理
	bool					m_bStopped;		///< 是否已停止
	StdThreadPtr			m_thrdWorker;	///< 工作线程

	// 动态库管理
	std::string		m_strModule;		///< 模块名称
	DllHandle		m_hInstCTP;			///< CTP动态库句柄
	typedef CThostFtdcTraderApi* (*CTPCreator)(const char *);
	CTPCreator		m_funcCreator;		///< CTP API创建函数指针

	// 缓存管理
	WtKVCache		m_eidCache;			///< 委托单号缓存（EntrustID）
	WtKVCache		m_oidCache;			///< 订单号缓存（OrderID）
};

